package com.lin.cloud.disk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.lin.cloud.disk.common.utils.DateUtils;
import com.lin.cloud.disk.common.utils.NumberUtils;
import com.lin.cloud.disk.entity.pojo.DirectoryClosure;
import com.lin.cloud.disk.entity.request.directory.*;
import com.lin.cloud.disk.service.IDirectoryClosureService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author ljc
 * @date 2021/1/22 18:02
 */
@Service(value = "directoryClosureServiceDocument")
@Slf4j
public class DirectoryClosureServiceDocumentImpl implements IDirectoryClosureService {

    @Resource
    private MongoTemplate mongoTemplate;


    @Override
    public void createDirectoryClosureList(List<DirectoryClosure> directoryClosureList) {
        if (CollectionUtil.isNotEmpty(directoryClosureList)) {
            // 批量插入
            directoryClosureList.forEach(item -> {
                item.setId(Long.parseLong(DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + NumberUtils.getRandom(10000, 99999)));
            });
            mongoTemplate.insertAll(directoryClosureList);
        }
    }

    @Override
    public List<DirectoryClosure> getAncestorList(GetAncestorListRequest request) {
        if (request.getDistance() < 0) {
            return Collections.EMPTY_LIST;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
                .and("userId").is(request.getUserId().toString())
                .and("descendant").in(request.getDescendantList())
                .and("distance").gte(request.getDistance())
        );
        return mongoTemplate.find(query, DirectoryClosure.class, DirectoryClosure.COLLECTION_NAME);
    }

    @Override
    public List<DirectoryClosure> getRootDirectoryList(GetRootDirectoryListRequest request) {

        // 查询条件
        Criteria criteria = Criteria.where("$where").is("this.descendant = this.ancestor")
                .and("userId").is(request.getUserId().toString())
                .and("distance").is(0)
                .and("isRoot").is(1)
                .and("companyId").is(request.getCompanyId().toString()
                );
        Query query = new Query();
        query.addCriteria(criteria);
        return mongoTemplate.find(query, DirectoryClosure.class, DirectoryClosure.COLLECTION_NAME);
    }


    @Override
    public int physicistRemoveDirectoryClosure(RemoveDirectoryRequest request) {
        Query query = new Query();
        query.addCriteria(Criteria.where("companyId").is(request.getUserDTO().getCompanyId().toString())
                .and("userId").is(request.getUserDTO().getId().toString())
                .orOperator(
                        Criteria.where("ancestor").in(request.getIdList()),
                        Criteria.where("descendant").in(request.getIdList())
                )
        );
        return (int) mongoTemplate.remove(query, DirectoryClosure.COLLECTION_NAME).getDeletedCount();
    }

    @Override
    public List<DirectoryClosure> getDescendantListAndMeByIdList(GetDescendantListAndMeByIdListRequest request) {
        if (CollectionUtil.isEmpty(request.getDescendantList())) {
            return Collections.EMPTY_LIST;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
                .and("userId").is(request.getUserId().toString())
                .and("ancestor").in(request.getDescendantList())
        );
        return mongoTemplate.find(query, DirectoryClosure.class, DirectoryClosure.COLLECTION_NAME);
    }

    @Override
    public int physicistMoveRemoveDirectoryClosure(MoveRemoveDirectoryRequest request) {
        Query query = new Query();
        query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
                .and("userId").is(request.getUserId().toString())
                .and("descendant").in(request.getDescendantIdList())
                .and("ancestor").in(request.getAncestorIdList())
//                .andOperator(
//                        Criteria.where("ancestor").in(request.getAncestorIdList()),
//                        Criteria.where("descendant").in(request.getDescendantIdList())
//                )
        );

//        if (CollectionUtil.isEmpty(request.getAncestorIdList())) {
//            query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
//                    .and("userId").is(request.getUserId().toString())
//                    .and("descendant").in(request.getDescendantIdList())
//            );
//        } else if (CollectionUtil.isEmpty(request.getDescendantIdList())) {
//            query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
//                    .and("userId").is(request.getUserId().toString())
//                    .and("ancestor").in(request.getAncestorIdList())
//            );
//        } else {
//            query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
//                    .and("userId").is(request.getUserId().toString())
//                    .andOperator(
//                            Criteria.where("ancestor").in(request.getAncestorIdList()),
//                            Criteria.where("descendant").in(request.getDescendantIdList())
//                    )
//            );
//        }

        return (int) mongoTemplate.remove(query, DirectoryClosure.COLLECTION_NAME).getDeletedCount();

    }

    /**
     * 获取下一级目录列表
     *
     * @param request
     * @return
     */
    @Override
    public List<DirectoryClosure> getNextLevelDirectoryList(GetNextLevelDirectoryListRequest request) {
        Query query = new Query();
        if (null == request.getDirectoryId()) {
            query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
                    .and("userId").is(request.getUserId().toString())
                    .and("isRoot").is(1)
            );
        } else {
            query.addCriteria(Criteria.where("companyId").is(request.getCompanyId().toString())
                    .and("userId").is(request.getUserId().toString())
                    .and("ancestor").is(request.getDirectoryId().toString())
                    .and("isRoot").is(0)
                    .and("distance").is(1)

            );
        }
        return mongoTemplate.find(query, DirectoryClosure.class, DirectoryClosure.COLLECTION_NAME);
    }

    /**
     * 删除祖先等于子孙的边
     *
     * @param request
     * @return
     */
    @Override
    public void removeAncestorEqDescendant(RemoveAncestorEqDescendantRequest request) {
        // 查询条件
        Criteria criteria = Criteria.where("$where").is("this.descendant = this.ancestor")
                .and("ancestor").in(request.getIdList())
                .and("userId").is(request.getUserId().toString())
                .and("distance").is(0)
                .and("isRoot").is(1)
                .and("companyId").is(request.getCompanyId().toString()
                );
        Query query = new Query();
        query.addCriteria(criteria);
        mongoTemplate.remove(query, DirectoryClosure.COLLECTION_NAME);
    }

    /**
     * 批量更新
     *
     * @param list
     */
    @Override
    public void batchUpdateDirectoryClosure(List<DirectoryClosure> list) {
        Query query = null;
        Update update = null;
        for (DirectoryClosure directoryClosure : list) {
            query = new Query();
            update = new Update();

            if (StringUtils.isNotBlank(directoryClosure.getAncestor())) {
                update.set("ancestor", directoryClosure.getAncestor());
            }

            if (StringUtils.isNotBlank(directoryClosure.getDescendant())) {
                update.set("descendant", directoryClosure.getDescendant());
            }

            if (null != directoryClosure.getDistance()) {
                update.set("distance", directoryClosure.getDistance());
            }

            if (null != directoryClosure.getIsRoot()) {
                update.set("isRoot", directoryClosure.getIsRoot());
            }

            query.addCriteria(Criteria.where("_id").is(directoryClosure.getId()));
            mongoTemplate.updateFirst(query, update, DirectoryClosure.class);
        }
    }

    /**
     * 批量删除
     * @param idList
     */
    @Override
    public void batchRemoveDirectoryClosure(List idList){
        if (CollectionUtil.isNotEmpty(idList)){
            Query query = new Query();
            query.addCriteria(Criteria.where("_id").in(idList));
            mongoTemplate.remove(query,DirectoryClosure.class);
        }
    }
}
